import zrender from 'zrender';

// import tool from './Tool';

/**
 * @desc Calculate the path
 */
class CountPath {
    overDistance = 30; // overflow distance

    /**
     * @desc get start points or end points
     * @param {object} node
     * @param {string} dirc
     */
    getFromOrToPoints(node, dirc) {
        let { x, y, points } = node;
        let { cx, cy } = [...points].filter(p => {
            return p.dirc === dirc;
        })[0];
        x += cx;
        y += cy;
        return [x, y];
    }

    /**
     * @desc get next points
     * @param {string} dire
     * @param {number} x
     * @param {number} y
     */
    getNextPoint(dire, x, y, overDistance) {
        switch (dire) {
            case 'left':
                x -= overDistance;
                break;
            case 'top':
                y -= overDistance;
                break;
            case 'right':
                x += overDistance;
                break;
            case 'bottom':
                y += overDistance;
                break;
        }
        return { x, y };
    }

    /**
     * @desc two rect distance
     */
    getRectDistance(fromNode, toNode) {
        let { x, y, width, height } = fromNode;
        let ydist = null;
        let xdist = null;
        let cx = null;
        let cy = null;

        if (toNode.x > fromNode.x) {
            xdist = toNode.x - x;
            cx = x + xdist / 2;
        } else {
            xdist = x - toNode.x;
            cx = toNode.x + xdist / 2;
        }

        if (toNode.y > fromNode.y) {
            ydist = toNode.y - fromNode.y;
            cy = toNode.y - ydist / 2;
        } else {
            ydist = fromNode.y - toNode.y;
            cy = fromNode.y - ydist / 2;
        }

        return { xdist, ydist, cx, cy };
    }

    /**
     * @desc get box size
     */
    getRectSize(node, overDistance) {
        let { x, y, width, height } = node;
        x -= overDistance;
        y -= overDistance;
        width += overDistance * 2;
        height += overDistance * 2;
        return { x, y, width, height, cx: x + width / 2, cy: y + height / 2 };
    }

    /**
     * @desc
     * @param {object} p1 {cx, cy}
     * @param {object} p2
     */
    judgeDist(p1, p2) {
        let x, y;
        if (p2.cx > p1.cx) {
            x = -1;
        } else {
            x = 1;
        }
        if (p2.cy > p1.cy) {
            y = -1;
        } else {
            y = 1;
        }
        return [x, y].join(',');
    }

    /**
     * @desc count points，data is link
     * @param {object} data
     */
    countLinePoints(data, zr) {
        const { fromNode, fromdire, todire, toNode } = data;
        let points = [];

        // 起点终点
        let [x1, y1] = this.getFromOrToPoints(fromNode, fromdire);
        let [x2, y2] = this.getFromOrToPoints(toNode, todire);

        // 判断距离
        let distance = this.getRectDistance(
            { width: fromNode.width, height: fromNode.height, x: x1, y: y1 },
            { width: toNode.width, height: toNode.height, x: x2, y: y2 }
        );

        // if (zr) {
        //     if (!this.zrDot) {
        //         this.zrDot = new zrender.Group();
        //         zr.add(this.zrDot);
        //     }
        //     this.zrDot.removeAll();
        //     this.zrDot.add(
        //         new zrender.Rect({
        //             z: 200,
        //             position: [distance.cx, distance.cy],
        //             shape: { width: 4, height: 4 },
        //             style: { fill: '#000' }
        //         })
        //     );
        //     this.zrDot.dirty();
        // }

        // console.log(distance);
        points.push([x1, y1]);

        if (fromNode.id === toNode.id) {
            let a = this.getNextPoint(fromdire, x1, y1, this.overDistance / 2);
            let b = this.getNextPoint(todire, x2, y2, this.overDistance / 2);
            // 获取外框
            let rect = this.getRectSize(fromNode, this.overDistance / 2);
            points.push([a.x, a.y]);
            switch (`${fromdire}-${todire}`) {
                case 'top-left':
                    points.push([rect.x, rect.y]);
                    break;
                case 'left-top':
                    points.push([rect.x, rect.y]);
                    break;
                case 'top-right':
                    points.push([rect.x + rect.width, rect.y]);
                    break;
                case 'right-top':
                    points.push([rect.x + rect.width, rect.y]);
                    break;
                case 'top-bottom':
                    points.push([rect.x, rect.y]);
                    points.push([rect.x, rect.y + rect.height]);
                    break;
                case 'bottom-top':
                    points.push([rect.x + rect.width, rect.y + rect.height]);
                    points.push([rect.x + rect.width, rect.y]);
                    break;
                case 'left-bottom':
                    points.push([rect.x, rect.y + rect.height]);
                    break;
                case 'bottom-left':
                    points.push([rect.x, rect.y + rect.height]);
                    break;
                case 'right-bottom':
                    points.push([rect.x + rect.width, rect.y + rect.height]);
                    break;
                case 'bottom-right':
                    points.push([rect.x + rect.width, rect.y + rect.height]);
                    break;
                case 'left-right':
                    points.push([rect.x, rect.y]);
                    points.push([rect.x + rect.width, rect.y]);
                    break;
                case 'right-left':
                    points.push([rect.x + rect.width, rect.y + rect.height]);
                    points.push([rect.x, rect.y + rect.height]);
                    break;
            }
            points.push([b.x, b.y]);
        } else {
            let a = this.getNextPoint(fromdire, x1, y1, this.overDistance);
            let b = this.getNextPoint(todire, x2, y2, this.overDistance);
            switch (`${fromdire}-${todire}`) {
                case 'top-top':
                    if (a.y < b.y) {
                        points.push([a.x, a.y]);
                        points.push([b.x, a.y]);
                    } else {
                        points.push([a.x, b.y]);
                        points.push([b.x, b.y]);
                    }
                    break;
                case 'bottom-bottom':
                    if (a.y < b.y) {
                        points.push([a.x, b.y]);
                        points.push([b.x, b.y]);
                    } else {
                        points.push([a.x, a.y]);
                        points.push([b.x, a.y]);
                    }
                    break;
                case 'left-left':
                    if (a.x < b.x) {
                        points.push([a.x, a.y]);
                        points.push([a.x, b.y]);
                    } else {
                        points.push([b.x, a.y]);
                        points.push([b.x, b.y]);
                    }
                    break;
                case 'right-right':
                    if (a.x < b.x) {
                        points.push([b.x, a.y]);
                        points.push([b.x, b.y]);
                    } else {
                        points.push([a.x, a.y]);
                        points.push([a.x, b.y]);
                    }
                    break;
                case 'left-top':
                    points.push([a.x, a.y]);
                    points.push([a.x, distance.cy]);
                    if (distance.cy > b.y) {
                        points.push([a.x, b.y]);
                    } else {
                        points.push([b.x, distance.cy]);
                    }
                    points.push([b.x, b.y]);
                    break;
                case 'right-top':
                    points.push([a.x, a.y]);
                    points.push([a.x, distance.cy]);
                    if (distance.cy > b.y) {
                        points.push([a.x, b.y]);
                    } else {
                        points.push([b.x, distance.cy]);
                    }
                    points.push([b.x, b.y]);
                    break;
                case 'top-bottom':
                    points.push([a.x, a.y]);
                    if (a.y < b.y) {
                        points.push([distance.cx, a.y]);
                        points.push([distance.cx, b.y]);
                    } else {
                        points.push([a.x, distance.cy]);
                        points.push([b.x, distance.cy]);
                    }
                    points.push([b.x, b.y]);
                    break;
                case 'bottom-top':
                    points.push([a.x, a.y]);
                    if (a.y > b.y) {
                        points.push([distance.cx, a.y]);
                        points.push([distance.cx, b.y]);
                    } else {
                        points.push([a.x, distance.cy]);
                        points.push([b.x, distance.cy]);
                    }
                    points.push([b.x, b.y]);
                    break;

                default:
                    points.push([a.x, a.y]);
                    points.push([a.x, distance.cy]);
                    points.push([b.x, distance.cy]);
                    points.push([b.x, b.y]);
            }
        }
        points.push([x2, y2]);

        return points;
    }
}

export default new CountPath();
